package com.mzkj.wanjulaile.mobile.api.modules.order.service;

import com.alibaba.fastjson.JSONObject;
import com.mzkj.common.data.StatusCode;
import com.mzkj.common.utils.*;
import com.mzkj.wanjulaile.mobile.api.common.entity.ResultEntity;
import com.mzkj.wanjulaile.mobile.api.common.service.BaseService;
import com.mzkj.wanjulaile.mobile.api.common.utils.RedisUtil;
import com.mzkj.wanjulaile.mobile.api.modules.account.entity.Account;
import com.mzkj.wanjulaile.mobile.api.modules.account.entity.VipCategory;
import com.mzkj.wanjulaile.mobile.api.modules.account.mapper.AccountMapper;
import com.mzkj.wanjulaile.mobile.api.modules.account.mapper.BuyVipMapper;
import com.mzkj.wanjulaile.mobile.api.modules.account.mapper.VipCategoryMapper;
import com.mzkj.wanjulaile.mobile.api.modules.account.mapper.VipSchemeMapper;
import com.mzkj.wanjulaile.mobile.api.modules.address.entity.Address;
import com.mzkj.wanjulaile.mobile.api.modules.appointment.mapper.AppointmentCollectionMapper;
import com.mzkj.wanjulaile.mobile.api.modules.coupon.entity.AccountCoupon;
import com.mzkj.wanjulaile.mobile.api.modules.coupon.mapper.AccountCouponMapper;
import com.mzkj.wanjulaile.mobile.api.modules.order.constant.Constant;
import com.mzkj.wanjulaile.mobile.api.modules.order.entity.DSHOrder;
import com.mzkj.wanjulaile.mobile.api.modules.order.entity.Order;
import com.mzkj.wanjulaile.mobile.api.modules.order.entity.OrderToy;
import com.mzkj.wanjulaile.mobile.api.modules.order.mapper.OrderMapper;
import com.mzkj.wanjulaile.mobile.api.modules.order.mapper.OrderToyMapper;
import com.mzkj.wanjulaile.mobile.api.modules.shoppingCart.mapper.ShoppingCartMapper;
import com.mzkj.wanjulaile.mobile.api.modules.stock.entity.Stock;
import com.mzkj.wanjulaile.mobile.api.modules.stock.mapper.StockMapper;
import com.mzkj.wanjulaile.mobile.api.modules.toy.entity.Toy;
import com.mzkj.wanjulaile.mobile.api.modules.toy.mapper.ToyMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * Created by ianly on 16/10/24.
 */
@Service
public class WXOrderService extends BaseService {
    @Autowired
    private OrderMapper orderDao;
    @Autowired
    private OrderToyMapper orderToyDao;
    @Autowired
    private StockMapper stockDao;
    @Autowired
    private ToyMapper toyDao;
    @Autowired
    private AccountMapper accountDao;
    @Autowired
    private VipSchemeMapper vipSchemeDao;
    @Value("${limit_date}")
    private Long orderLimitDate; //复购周期
    @Value("${shipFee}")
    private Integer shipFee; //配送费
    @Value("${orderTimeOut}")
    private int orderTimeOut;
    @Autowired
    private ShoppingCartMapper shoppingCartDao;
    @Autowired
    private AppointmentCollectionMapper appointmentCollectionDao;
    @Autowired
    private BuyVipMapper buyVipDao;
    @Autowired
    private AccountCouponMapper accountCouponMapper;
    @Autowired
    private DelayService delayService;
    @Autowired
    private VipCategoryMapper vipCategoryMapper;
    @Value("${vipLeftDays}")
    private int vipLeftDays;

    /**
     * 复购 校验用户下单周期是否在周期天内
     *
     * @param accountId
     * @param result
     * @return
     */
    public boolean validateLimitDate(String accountId, ResultEntity<Order> result, String appointDate) {
        Account account = accountDao.get(accountId);
        Order lastOrder = orderDao.getLastOrderByAccountId2(accountId);
        if (lastOrder != null) {
            if (lastOrder.getPayStatus() == 0) {
                  result.setStatusCode(StatusCode.SC400501.getValue());
                  result.setMsg(StatusCode.SC400501.getDesc());
                return true;
            }
            if (lastOrder.getStatus().equals(Constant.ORDER_CREATE)) {
                result.setStatusCode(StatusCode.SC400502.getValue());
                result.setMsg(StatusCode.SC400502.getDesc());
                return true;
            }
            //if (account.getVipType().equals(4)) {
            //    result.setMsg("体验会员只可享受一次租赁,如需换购请续费正式会员");
            //    result.setStatusCode("40000");
            //    return true;
            //}
            if (lastOrder.getReceiveDate() == null) {
                  result.setStatusCode(StatusCode.SC40006.getValue());
                result.setMsg(StatusCode.SC40006.getDesc());
                return true;
            }
            //以上一次预约时间算起间隔orderLimitDate天
            Long limitDate = DateUtils.getDistanceOfTwoDate(DateUtils.parseDate(lastOrder.getAppointDate2()), new Date());
            if (limitDate < orderLimitDate) {
                result.setStatusCode(StatusCode.SC40013.getValue());
                result.setMsg("每次租赁最短时间为" + orderLimitDate + "天,请在" + (orderLimitDate - limitDate) + "天之后再下单");
                return true;
            }
            //到期三天前不让下单(含到期日)
            if(account != null && account.getVipEnd() != null){
                Long leftDays = DateUtils.getDistanceOfTwoDate(new Date(),DateUtils.parseDate(account.getVipEnd()));
                if (leftDays < vipLeftDays){
                    result.setStatusCode(StatusCode.SC40016.getValue());
                    result.setMsg(StatusCode.SC40016.getDesc());
                    return true;
                }
            }

            //配送日期是否在vip时效范围内
            String vipEnd = account.getVipEnd();
            if (StringUtils.isNotEmpty(vipEnd) && DateUtils.parseDate(vipEnd).compareTo(DateUtils.parseDate(appointDate.substring(0,appointDate.indexOf("("))))<=0){
                result.setStatusCode(StatusCode.SC40009.getValue());
                result.setMsg(StatusCode.SC40009.getDesc());
                return true;
            }
        }
        return false;
    }

    /**
     * 用户下单玩具的库存
     *
     * @param accountId
     * @param buyToy
     * @param toyIdList
     * @param result
     */
    public boolean validateStock(String accountId, Map<String, Integer> buyToy, List<String> toyIdList, ResultEntity<Order> result) {
        Account account = accountDao.get(accountId);
        VipCategory vipCategory = vipCategoryMapper.getByType(account.getVipType());
        //租赁玩具星值数
        int rentToyStars = 0;
        for (String nowId : toyIdList) {
            Stock stock = stockDao.getByToyId(nowId);
            if (stock == null || (stock.getRealCount() - buyToy.get(nowId) < 0)) {
                result.setStatusCode(StatusCode.SC4003.getValue());
                result.setMsg(StatusCode.SC4003.getDesc());
                return true;
            }
        }
        for (String toyId : buyToy.keySet()) {
            Toy toy = toyDao.get(toyId);
            rentToyStars += toy.getStar();
        }
        if (rentToyStars > vipCategory.getStar()) {
            result.setStatusCode(StatusCode.SC40011.getValue());
            result.setMsg("所选玩具星值已高于当前会员套餐,请选择退还玩具");
            return true;
        }
        return false;
    }

    /**
     * 生成订单
     *
     * @param params
     */
    @Transactional(readOnly = false)
    public Order saveOrder(Map<String, Object> params) {
        Order order = new Order();
        order.setShipFee(shipFee);
        order.setAccount(new Account((String) params.get("accountId")));
        order.setOrderNumber(OrderUilts.generateOrderNumber());
        order.setAddress(new Address((String) params.get("addressId")));
        order.setStatus(Constant.ORDER_CREATE);
        order.setAppointDate((String) params.get("appointDate"));
        // 上一次订单
        Order lastOrder = orderDao.getLastOrderByAccountId((String) params.get("accountId"));
        Account account = accountDao.get((String) params.get("accountId"));
        order.setCurVipType(account.getVipType());
        if (StringUtils.isNotEmpty((String)params.get("accountCouponId"))){
            AccountCoupon accountCoupon=new AccountCoupon();
            accountCoupon.setId((String)params.get("accountCouponId"));
            AccountCoupon accountCoupon1=accountCouponMapper.getById(accountCoupon);
            order.setCouponVal(Integer.valueOf(accountCoupon1.getCoupon().getFaceValue()));
            order.setAccountCoupon(accountCoupon1);
            //减运费抵用券
            accountCoupon.setCount(accountCoupon1.getCount()-1);
            if(accountCoupon.getCount()==0){
                accountCoupon.setDelFlag("1");
            }
            accountCouponMapper.update(accountCoupon);
        }
        order.preInsert();
        orderDao.saveOrder(order);
        // 订单玩具
        saveOrderToy(order, params);
        //清除购物车
        List<String> toyIdList = (List<String>) params.get("toyIdList");
        String accountId = (String) params.get("accountId");
        shoppingCartDao.batchDelete(toyIdList, accountId);
        //清除预约
        appointmentCollectionDao.batchDelete(toyIdList, accountId);
        //减库存
        updateStock(params);

        //存入 redis  入队列 30分钟不支付取消订单
        saveRedisAndQueue(order);
        return orderDao.get(order);
    }

    private void saveRedisAndQueue(Order order) {
        //int orderTimeOut = 120;
        DSHOrder dshOrder = new DSHOrder(order.getId(),orderTimeOut);
        //入队
        delayService.add(dshOrder);
        //入redis
        Object json = JSONObject.toJSON(dshOrder);
        String dshOrderJson = json.toString();
        RedisUtil.set(Constant.RedisKey_DSHORDER_PREFIX+order.getId(),dshOrderJson);
        logger.info("下单,订单入队,存redis中>>>>>>>>>"+order.getId());
    }

    /**
     * 复购 上一次订单中的玩具状态
     *
     * @param params
     * @param lastOrder
     */
    private void updateOldToyStatus(Map<String, Object> params, Order lastOrder) {
        //退还玩具
        List<String> reToyIdList = (List<String>) params.get("reToyIdList");
        updateOrderToyStatusToNew(lastOrder, reToyIdList, Constant.ORDER_TOY_RETURN);
        //续租玩具
        List<String> oldReToyIdList = (List<String>) params.get("oldReToyIdList");
        updateOrderToyStatusToNew(lastOrder, oldReToyIdList, Constant.ORDER_TOY_RENTING);
    }

    private void updateOrderToyStatusToNew(Order lastOrder, List<String> reToyIdList, Integer toyStatus) {
        if (!Collections3.isEmpty(reToyIdList)) {
            for (String id : reToyIdList) {
                OrderToy orderToy = new OrderToy();
                orderToy.setOrderId(lastOrder.getId());
                orderToy.setToy(new Toy(id));
                orderToy.setToyStatus(toyStatus);
                orderToy.setToyStatusLast(toyStatus);
                orderToyDao.updateStatusByOrderIdAndToyId(orderToy);
            }
        }
    }

    /**
     * 更新库存
     *
     * @param params
     */
    private void updateStock(Map<String, Object> params) {
        List<String> toyIds = (List<String>) params.get("toyIdList");
        for (String toyId : toyIds) {
            Stock stock = stockDao.getByToyId(toyId);
            stock.setRealCount(stock.getRealCount() - 1);
            stockDao.update(stock);
        }
    }

    /**
     * 生成订单玩具表
     *
     * @param order
     * @param params
     */
    private void saveOrderToy(Order order, Map<String, Object> params) {
        //本次玩具
        List<String> toyIds = (List<String>) params.get("toyIdList");
        insertOrderToy(order, toyIds, Constant.ORDER_TOY_SHIPPING);
        //复购 续租玩具
        List<String> oldReToyIds = (List<String>) params.get("oldReToyIdList");
        if (!Collections3.isEmpty(oldReToyIds)) {
            insertOrderToy(order, oldReToyIds, Constant.ORDER_TOY_RENTING);
        }
    }

    private void insertOrderToy(Order order, List<String> toyIds, Integer toyStatus) {
        for (String toyId : toyIds) {
            OrderToy orderToy = new OrderToy();
            orderToy.setToyCount(1);
            orderToy.setToy(new Toy(toyId));
            orderToy.setOrderId(order.getId());
            orderToy.setToyStatus(toyStatus);
            orderToy.setToyStatusLast(toyStatus);
            orderToy.preInsert();
            if (toyStatus.equals(Constant.ORDER_TOY_RETURNING)){
                //回收
                orderToy.setType(1);
            }
            if (toyStatus.equals(Constant.ORDER_TOY_RENTING)){
                //续租玩具
                orderToy.setType(2);
            }
            orderToyDao.insert(orderToy);
        }
    }

    @Transactional
    public synchronized ResultEntity<Order> toSaveOrder(Map<String, Object> params, Map<String, Integer> buyToy, ResultEntity<Order> result) {
        //校验库存
        boolean validateStock = validateStock((String) params.get("accountId"), buyToy, (List<String>) params.get("toyIdList"), result);
        if (validateStock){
            //库存不足
            return result;
        }else{
            //生成订单
            Order order = saveOrder(params);
            result.setStatusCode(StatusCode.SC0.getValue());
            result.setData(order);
            result.setMsg(StatusCode.SC0.getDesc());
        }
        return result;
    }
}
